#!/bin/bash

# CentOS 7.9 Minimal 系统完整初始化脚本
# 功能：系统安全加固、性能优化、常用工具安装、基础环境配置
# 使用方法：chmod +x init_system.sh && ./init_system.sh

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'  # 紫色
CYAN='\033[0;36m'
NC='\033[0m' # 无颜色

# 日志函数
log() {
    echo -e "${PURPLE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} ${GREEN}[INFO]${NC} - $1"
}

warn() {
    echo -e "${PURPLE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} ${YELLOW}[WARN]${NC} - $1"
}

error() {
    echo -e "${PURPLE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} ${RED}[ERROR]${NC} - $1" >&2
    exit 1
}

# 时间戳函数（紫色）
timestamp() {
    echo -e "${PURPLE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC}"
}

# 检查是否以root用户运行
check_root() {
    if [[ $EUID -ne 0 ]]; then
        error "此脚本必须以root权限运行"
    fi
}

# 检查网络连接
check_network() {
    log "检查网络连接..."
    if ! ping -c 1 -W 3 baidu.com &> /dev/null; then
        error "网络连接失败，请检查网络配置"
    fi
}

# 配置阿里云yum源
configure_yum_repos() {
    log "配置阿里云yum源..."
    
    # 创建备份目录
    local backup_dir="/opt/backup_sys_file/$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$backup_dir/yum.repos.d"
    
    # 备份原有的repo文件
    if [ -d /etc/yum.repos.d/ ]; then
        cp -r /etc/yum.repos.d/* "$backup_dir/yum.repos.d/" 2>/dev/null || true
        log "原有repo文件已备份到: $backup_dir/yum.repos.d/"
    fi
    
    # 下载阿里云CentOS-Base.repo
    curl -so /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    if [ $? -ne 0 ]; then
        error "下载CentOS-Base.repo失败"
    fi

    # 下载阿里云epel.repo
    curl -so /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
    if [ $? -ne 0 ]; then
        error "下载epel.repo失败"
    fi

    # 清理原有repo文件（保留刚刚下载的两个）
    find /etc/yum.repos.d/ -name "*.repo" ! -name "CentOS-Base.repo" ! -name "epel.repo" -exec mv {} "$backup_dir/yum.repos.d/" \; 2>/dev/null || true

    # 生成缓存
    yum clean all
    yum makecache
    
    log "阿里云yum源配置完成，原有配置已备份到: $backup_dir"
}

# 备份原始文件
backup_files() {
    log "备份重要系统文件..."
    
    # 创建备份目录
    local backup_dir="/opt/backup_sys_file/$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$backup_dir"
    
    # 备份重要配置文件
    local files_to_backup=(
        /etc/ssh/sshd_config
        /etc/sysctl.conf
        /etc/security/limits.conf
        /etc/profile
        /etc/bashrc
        /etc/hosts
        /etc/sysconfig/network
        /etc/pam.d/system-auth
    )
    
    for file in "${files_to_backup[@]}"; do
        if [[ -f "$file" ]]; then
            cp "$file" "$backup_dir/"
        fi
    done
    
    log "备份已完成，存放在: $backup_dir"
}

# 更新系统
update_system() {
    log "开始更新系统..."
    yum makecache fast
    yum update -y
    log "系统更新完成"
}

# 安装常用工具和软件
install_packages() {
    log "安装常用工具和软件..."
    
    # 基础工具
    yum install -y epel-release
    yum install -y wget sshpass curl telnet net-tools vim-enhanced tree htop iftop iotop 
    yum install -y lsof psmisc nc nmap bind-utils traceroute tcpdump
    yum install -y zip unzip bzip2 p7zip p7zip-plugins
    yum install -y git jq bc sysstat dstat
    
    # 开发工具
    yum groupinstall -y "Development Tools"
    yum install -y make cmake gcc gcc-c++ autoconf automake libtool
    
    # Python 环境
    yum install -y python3 python3-devel python3-pip
    pip3 install --upgrade pip
    
    # 其他有用工具
    yum install -y yum-utils device-mapper-persistent-data lvm2
    yum install -y chrony ntpdate
    
    # 安装SSH相关工具
    yum install -y openssh-server openssh-clients
    
    log "软件安装完成"
}

# 生成SSH密钥
generate_ssh_keys() {
    log "生成SSH密钥对..."
    
    # 创建.ssh目录如果不存在
    mkdir -p /root/.ssh
    chmod 700 /root/.ssh
    
    # 检查是否已存在密钥，如果不存在则生成
    if [ ! -f /root/.ssh/id_rsa ]; then
        ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -N "" -q
        log "已生成新的SSH密钥对"
    else
        log "SSH密钥已存在，跳过生成"
    fi
    
    # 设置正确的权限
    chmod 600 /root/.ssh/id_rsa 2>/dev/null || true
    chmod 644 /root/.ssh/id_rsa.pub 2>/dev/null || true
    
    log "SSH密钥配置完成"
}

# 配置主机信息和时区
configure_system() {
    log "配置系统基本信息..."
    
    # 设置主机名（请根据实际情况修改）
    read -p "请输入主机名: " hostname
    hostnamectl set-hostname "$hostname"
    
    # 设置时区为上海
    timedatectl set-timezone Asia/Shanghai
    
    # 启用NTP时间同步
    yum install -y chrony
    systemctl enable chronyd
    systemctl start chronyd
    chronyc sources
    
    log "系统基本配置完成"
}

# 安全加固（修改：采用更安全可靠的SSH配置方法）
secure_system() {
    log "开始系统安全加固..."
    local sshd_config="/etc/ssh/sshd_config"
    local backup_file="${sshd_config}.bak.$(date +%Y%m%d%H%M%S)"

    # 0. 首先备份原始配置文件！
    cp "$sshd_config" "$backup_file"
    log "SSH配置文件已备份至: $backup_file"

    # 1. 使用明确命令确保关键认证参数正确设置
    # 确保UsePAM开启（这是必须的）
    sed -i 's/^#*UsePAM.*/UsePAM yes/' "$sshd_config"

    # 确保允许root登录（根据您的需求）
    sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' "$sshd_config"

    # 确保允许公钥认证
    sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' "$sshd_config"

    # 确保密码认证是关闭的（推荐，与密钥登录更配）
    sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' "$sshd_config"

    # 2. 追加明确的配置到文件末尾（如果上面sed未找到匹配行，则添加）
    # 这是一种保险策略，确保参数存在且值正确
    grep -q '^UsePAM' "$sshd_config" || echo "UsePAM yes" >> "$sshd_config"
    grep -q '^PermitRootLogin' "$sshd_config" || echo "PermitRootLogin yes" >> "$sshd_config"
    grep -q '^PubkeyAuthentication' "$sshd_config" || echo "PubkeyAuthentication yes" >> "$sshd_config"
    grep -q '^PasswordAuthentication' "$sshd_config" || echo "PasswordAuthentication no" >> "$sshd_config"

    # 3. 设置其他安全参数（这些sed通常更安全，因为注释格式比较标准）
    sed -i 's/^#*MaxAuthTries.*/MaxAuthTries 3/' "$sshd_config"
    sed -i 's/^#*ClientAliveInterval.*/ClientAliveInterval 300/' "$sshd_config"
    sed -i 's/^#*ClientAliveCountMax.*/ClientAliveCountMax 2/' "$sshd_config"
    sed -i 's/^#*PermitEmptyPasswords.*/PermitEmptyPasswords no/' "$sshd_config"

    # 4. 配置防火墙
    systemctl enable firewalld
    systemctl start firewalld
    firewall-cmd --permanent --add-port=22/tcp
    firewall-cmd --reload
    
    # 5. 配置fail2ban防止暴力破解
    yum install -y fail2ban
    cat > /etc/fail2ban/jail.local << EOF
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/secure
maxretry = 3
bantime = 3600
EOF
    systemctl enable fail2ban
    systemctl start fail2ban
    
    # 6. 重启SSH服务前，检查配置语法是否正确！
    log "检查SSH配置语法..."
    if ! sshd -t -f "$sshd_config"; then
        error "SSH配置语法检查失败！已保留备份文件: $backup_file。请手动修复。"
    fi

    # 7. 语法检查通过后，重启服务
    systemctl restart sshd
    log "SSH服务已重启，新配置生效。"

    # 8. 禁用不必要的服务
    systemctl disable postfix
    systemctl stop postfix
    
    # 9. 配置文件权限
    chmod 600 /etc/ssh/ssh_host_*_key 2>/dev/null || true
    chmod 644 /etc/ssh/ssh_host_*_key.pub 2>/dev/null || true
    
    # 10. 设置密码策略
    sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t90/' /etc/login.defs
    sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t7/' /etc/login.defs
    sed -i 's/PASS_MIN_LEN\t5/PASS_MIN_LEN\t8/' /etc/login.defs
    
    # 11. 配置历史命令记录
    echo 'export HISTSIZE=10000' >> /etc/profile
    echo 'export HISTFILESIZE=10000' >> /etc/profile
    echo 'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "' >> /etc/profile
    echo 'export PROMPT_COMMAND="history -a"' >> /etc/profile
    
    log "系统安全加固完成"
}

# 内核参数优化
optimize_kernel() {
    log "优化内核参数..."
    
    # 备份原sysctl配置
    cp /etc/sysctl.conf /etc/sysctl.conf.bak
    
    # 添加优化参数
    cat >> /etc/sysctl.conf << EOF

# 系统优化参数
# 网络优化
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.rmem_default = 262144
net.core.rmem_max = 67108864
net.core.wmem_default = 262144
net.core.wmem_max = 67108864
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_fastopen = 3

# 内存优化
vm.swappiness = 10
vm.overcommit_memory = 1
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10
vm.dirty_expire_centisecs = 3000
vm.dirty_writeback_centisecs = 500

# 文件系统优化
fs.file-max = 2097152
fs.nr_open = 2097152
fs.inotify.max_user_instances = 8192
fs.inotify.max_user_watches = 524288
EOF
    
    # 应用配置
    sysctl -p
    
    log "内核参数优化完成"
}

# 文件描述符和进程限制优化
optimize_limits() {
    log "优化系统资源限制..."
    
    cat >> /etc/security/limits.conf << EOF

# 自定义资源限制
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
root soft nproc unlimited
root hard nproc unlimited
root soft nofile unlimited
root hard nofile unlimited
EOF
    
    # 配置系统级限制
    echo "fs.nr_open = 2097152" >> /etc/sysctl.conf
    echo "fs.file-max = 2097152" >> /etc/sysctl.conf
    
    log "系统资源限制优化完成"
}

# 配置别名和提示符
configure_shell() {
    log "配置Shell环境..."
    
    # 为root用户配置个性化提示符
    cat > /root/.bashrc << EOF

# 自定义配置
export PS1='\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
alias ll='ls -alFh --color=auto'
alias la='ls -A --color=auto'
alias l='ls -CF --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
alias h='history'
alias cls='clear'
alias ports='netstat -tulanp'
alias update='yum update -y'
alias install='yum install -y'
alias remove='yum remove -y'
alias vi='vim'

# 安全相关别名
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# 系统监控别名
alias meminfo='free -m -l -t'
alias cpuinfo='lscpu'
alias diskusage='df -h'
alias folderusage='du -ch | grep total'
alias most='du -hsx * | sort -rh | head -10'

# 网络相关别名
alias ping='ping -c 5'
alias myip='curl http://ipecho.net/plain; echo'
alias listen='lsof -i -P -n | grep LISTEN'

# SSH相关别名
alias ssh-keygen='ssh-keygen -t rsa -b 4096'
alias ssh-copy='echo "使用: ssh-copy-id user@hostname 来复制密钥"'
EOF
    
    # 使配置生效
    source /root/.bashrc
    
    log "Shell环境配置完成"
}

# 配置vim
configure_vim() {
    log "配置Vim编辑器..."
    
    cat > /root/.vimrc << EOF
set nocompatible
set backspace=2
set syntax=on
set number
set showmatch
set ignorecase
set smartcase
set incsearch
set autowrite
set hidden
set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
set encoding=utf-8
set fileencodings=utf-8,gbk
set hlsearch
set cursorline
set ruler
set laststatus=2
set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%04l,%04v][%p%%]\ [LEN=%L]
syntax enable
filetype plugin on
filetype indent on
EOF
    
    # 复制到所有用户
    cp /root/.vimrc /etc/skel/
    
    log "Vim配置完成"
}

# 创建常用目录结构
create_directories() {
    log "创建常用目录结构..."
    
    mkdir -p /data/{www,logs,backup,scripts,temp}
    mkdir -p /opt/{apps,config,tools}
    mkdir -p /etc/scripts
    
    chmod 755 /data /opt
    
    log "目录结构创建完成"
}

# 安装监控工具
install_monitoring_tools() {
    log "安装系统监控工具..."
    
    # 安装和配置sysstat
    yum install -y sysstat
    sed -i 's/^HISTORY=.*/HISTORY=30/' /etc/sysconfig/sysstat
    systemctl enable sysstat
    systemctl start sysstat
    
    # 安装日志轮转工具
    yum install -y logrotate
    
    # 安装htop替代top
    yum install -y htop
    
    log "监控工具安装完成"
}

# 配置计划任务
configure_cron() {
    log "配置计划任务..."
    
    # 添加系统维护任务
    cat > /etc/cron.d/daily_maintenance << EOF
# 每天凌晨清理临时文件
0 2 * * * root find /tmp -type f -atime +7 -delete
# 每周清理软件包缓存
0 3 * * 0 root yum clean all
# 每月1号更新locate数据库
0 5 1 * * root updatedb
EOF
    
    # 添加日志轮转检查
    cat > /etc/cron.daily/logrotate << EOF
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=\$?
if [ \$EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [\$EXITVALUE]"
fi
exit 0
EOF
    
    chmod +x /etc/cron.daily/logrotate
    
    log "计划任务配置完成"
}

# 创建系统健康检查脚本
create_healthcheck_script() {
    log "创建系统健康检查脚本..."
    
    cat > /root/healthcheck.sh << 'EOF'
#!/bin/bash

# 系统健康检查脚本

echo "===== 系统健康检查报告 ====="
echo "生成时间: $(date)"
echo ""

echo "----- 系统信息 -----"
echo "主机名: $(hostname)"
echo "运行时间: $(uptime | awk -F',' '{print $1}')"
echo "系统版本: $(cat /etc/redhat-release)"
echo "内核版本: $(uname -r)"
echo ""

echo "----- CPU使用情况 -----"
top -bn1 | head -5
echo ""

echo "----- 内存使用情况 -----"
free -h
echo ""

echo "----- 磁盘使用情况 -----"
df -h
echo ""

echo "----- 磁盘I/O情况 -----"
iostat -x 1 2 | tail -n +4
echo ""

echo "----- 网络连接情况 -----"
netstat -s | head -20
echo ""

echo "----- 当前连接数 -----"
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
echo ""

echo "----- 服务状态 -----"
systemctl list-units --type=service --state=running | head -10
echo ""

echo "----- 最近登录用户 -----"
last -n 5
echo ""

echo "----- 系统日志最后10条错误 -----"
journalctl -p 3 -xb --no-pager | tail -10
echo ""

echo "===== 检查完成 ====="
EOF
    
    chmod +x /root/healthcheck.sh
    
    log "健康检查脚本创建完成"
}

# 显示完成信息
show_completion() {
    echo ""
    echo -e "${PURPLE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} ${GREEN}===== 系统初始化完成 =====${NC}"
    echo ""
    echo -e "${BLUE}已完成以下配置：${NC}"
    echo "✓ 阿里云yum源配置"
    echo "✓ 系统更新和基础工具安装"
    echo "✓ SSH密钥对生成"
    echo "✓ 主机名和时区配置"
    echo "✓ SSH安全配置（保持端口22，允许root登录）"
    echo "✓ 防火墙配置"
    echo "✓ 内核参数和系统限制优化"
    echo "✓ Shell环境和Vim配置"
    echo "✓ 目录结构创建"
    echo "✓ 监控工具和计划任务配置"
    echo ""
    echo -e "${YELLOW}重要提醒：${NC}"
    echo "1. SSH保持默认端口22，root登录已启用"
    echo "2. 已配置fail2ban防止暴力破解"
    echo "3. SSH密钥对已生成，位于 /root/.ssh/"
    echo "4. 建议立即修改root密码为强密码"
    echo "5. 建议重新登录使部分配置生效"
    echo ""
    echo -e "系统健康检查脚本位置: ${GREEN}/root/healthcheck.sh${NC}"
    echo -e "系统备份位置: ${GREEN}/opt/backup_sys_file/*${NC}"
    echo -e "SSH公钥位置: ${GREEN}/root/.ssh/id_rsa.pub${NC}"
    echo ""
}

# 主执行函数
main() {
    log "开始执行CentOS 7.9系统初始化脚本"
    
    check_root
    check_network
    configure_yum_repos  # 配置阿里云yum源
    backup_files
    update_system
    install_packages
    generate_ssh_keys    # 生成SSH密钥对
    configure_system
    secure_system
    optimize_kernel
    optimize_limits
    configure_shell
    configure_vim
    create_directories
    install_monitoring_tools
    configure_cron
    create_healthcheck_script
    show_completion
    
    log "初始化脚本执行完毕，建议重启系统"
    read -p "是否立即重启系统? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        reboot
    fi
}

# 执行主函数
main "$@"